package concurrent.thread;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import sun.misc.Unsafe;
import sun.reflect.Reflection;

import java.lang.reflect.Field;

/**
 * @program JavaBase
 * @description:
 * @author: zhanglu
 * @create: 2021-05-09 18:41:00
 */
@Slf4j
public class UnsafeTest {

    private volatile long state = 0;

    /**
     * java.lang.SecurityException: Unsafe
     * @throws NoSuchFieldException
     */
    @Test
    public void test01() throws NoSuchFieldException {
        Unsafe unsafe = Unsafe.getUnsafe();
        long stateOffset = unsafe.objectFieldOffset(UnsafeTest.class.getDeclaredField("state"));
        log.info(stateOffset + "");
        boolean b = unsafe.compareAndSwapInt(new UnsafeTest(), stateOffset, 0, 1);
        log.info(b + "");
    }

    /**
     * 反射拿到unsafe
     */
    @Test
    public void test02() throws Exception {
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        Unsafe unsafe = (Unsafe) field.get(null);
        long stateOffset = unsafe.objectFieldOffset(UnsafeTest.class.getDeclaredField("state"));

        UnsafeTest unsafeTest = new UnsafeTest();
        log.info(stateOffset + "-" + unsafeTest.state);
        boolean b = unsafe.compareAndSwapInt(unsafeTest, stateOffset, 0, 1);
        log.info(b + "-" + unsafeTest.state);
        long c = unsafe.getLongVolatile(unsafeTest, stateOffset);
        log.info(c + "-" + unsafeTest.state);
    }

}
